package com.lcifn.middleware.rpc.client.stub;

import com.lcifn.middleware.rpc.serializer.SerializerSupport;
import com.lcifn.middleware.rpc.transport.Transport;
import com.lcifn.middleware.rpc.transport.command.Code;
import com.lcifn.middleware.rpc.transport.command.Command;
import com.lcifn.middleware.rpc.transport.command.Header;
import com.lcifn.middleware.rpc.transport.command.ResponseHeader;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @author lichao
 * @date 2021/1/31 14:33
 */
public class AbstractStub implements Stub{
    /**
     * 传输实现
     */
    protected Transport transport;

    /**
     * 服务远程调用
     * @param request
     * @return byte[]
     * @author lichao 2021/1/31 18:39
     */
    protected byte[] invokeRemote(RpcRequest request) {
        Header header = new Header(RequestIdSupport.next(), ServiceType.RPC_REQUEST, 0);
        byte[] payload = SerializerSupport.serialize(request);
        Command command = new Command(header, payload);

        try {
            CompletableFuture<Command> response = transport.send(command);
            Command respCommand = response.get();
            ResponseHeader respHeader = (ResponseHeader) respCommand.getHeader();
            if (respHeader.getCode() == Code.SUCCESS.getCode()) {
                return respCommand.getPayload();
            } else {
                throw new RuntimeException(respHeader.getError());
            }
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置传输实现
     *
     * @param transport
     * @return void
     * @author lichao 2021/1/31 14:34
     */
    @Override
    public void setTransport(Transport transport) {
        this.transport = transport;
    }
}
